package com.bingo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bingo.common.R;
import com.bingo.dao.FeedLossMapper;
import com.bingo.entity.*;
import com.bingo.entity.dto.DailyLoss;
import com.bingo.entity.dto.everyDayForm.EveryDayFeedLoss;
import com.bingo.entity.dto.FeedGainWeight;
import com.bingo.entity.dto.intermediary.SiteFeedLoss;
import com.bingo.entity.dto.resp.*;
import com.bingo.entity.dto.todayForm.TodayFeedLoss;
import com.bingo.service.*;
import com.bingo.until.HostHolder;
import com.bingo.until.IsToday;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

@Service
public class FeedLossServiceImpl extends ServiceImpl<FeedLossMapper, FeedLoss> implements FeedLossService {
    private HisPoolService hisPoolService;
    @Autowired
    public void setPoolService(HisPoolService hisPoolService) {
        this.hisPoolService = hisPoolService;
    }

    private HostHolder hostHolder;
    @Autowired
    public void setHostHolder(HostHolder hostHolder) {
        this.hostHolder = hostHolder;
    }

    private CurPoolService curPoolService;
    @Autowired
    public void setPrePoolService(CurPoolService curPoolService) {
        this.curPoolService = curPoolService;
    }

    private BaseDataService baseDataService;
    @Autowired
    public void setBaseDataService(BaseDataService baseDataService) {
        this.baseDataService = baseDataService;
    }

    private SiteService siteService;
    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    //新增食耗记录
    @Override
    public R add(String poolNo, Double feed, Integer loss, Double lossWeight, Date date, String userId) {

        //获取当前操作用户的ID
        userId = hostHolder.getUser().getUserId();

        //查询该塘
        CurPool pool = curPoolService.getCurPoolByNo(poolNo);
        if (pool==null){
            return R.error("该塘不存在！");
        }
        if (pool.getType()==0){
            return R.error("该塘是空塘！");
        }

        //查询是否已经存在当天该塘记录
        QueryWrapper<FeedLoss> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pool_no", poolNo);
        queryWrapper.eq("date", date);
        FeedLoss old = this.getOne(queryWrapper);

        //填充数据
        FeedLoss feedLoss = new FeedLoss();
        feedLoss.setPoolNo(poolNo);
        feedLoss.setFeed(feed);
        feedLoss.setLoss(loss);
        feedLoss.setLossWeight(lossWeight);
        feedLoss.setType(pool.getType());
        feedLoss.setUserId(userId);
        feedLoss.setReportDate(new Date(System.currentTimeMillis()));
        feedLoss.setDate(date);
        String coefficient = "";
        //查询系数
        if (feedLoss.getType()==1){
            coefficient = baseDataService.selectValueByName("coefficient1");
            feedLoss.setCoefficient(Double.parseDouble(coefficient));
        }else {
            coefficient = baseDataService.selectValueByName("coefficient2");
            feedLoss.setCoefficient(Double.parseDouble(coefficient));
        }

        //还未存在当天该塘记录
        if (old==null){
            //保存
            this.save(feedLoss);
            //修改当前塘状态
            //增重
            pool.setWeight(pool.getWeight()+feed/Double.parseDouble(coefficient));
            //减重
            pool.setWeight(pool.getWeight()-lossWeight);
            //损耗
            pool.setQuantity(pool.getQuantity()-loss);
            curPoolService.updateById(pool);

            //如果不是当天
            if(!IsToday.isToday(date)){
                QueryWrapper<HisPool> wrapper = new QueryWrapper<>();
                wrapper.eq("pool_no", poolNo);
                wrapper.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list = hisPoolService.list(wrapper);
                for (HisPool hisPool1 : list) {

                    hisPool1.setWeight(pool.getWeight()+feed/Double.parseDouble(coefficient));
                    //减重
                    hisPool1.setWeight(pool.getWeight()-lossWeight);
                    //损耗
                    hisPool1.setQuantity(hisPool1.getQuantity()-loss);
                    hisPoolService.updateById(hisPool1);
                }
            }

        }
        //已经存在当天该塘记录
        else {
            //对比两条数据的差值
            double feedDiff = feedLoss.getFeed()-old.getFeed();
            int lossDiff = feedLoss.getLoss()-old.getLoss();
            double lossWeightDiff = feedLoss.getLossWeight()-old.getLossWeight();

            //修改之前的食耗记录
            old.setFeed(feed);
            old.setLoss(loss);
            old.setLossWeight(lossWeight);
            this.updateById(old);


            //修改当前塘状态
            //增重
            pool.setWeight(pool.getWeight()+feedDiff/Double.parseDouble(coefficient));
            //减重
            pool.setWeight(pool.getWeight()-lossWeightDiff);
            //损耗
            pool.setQuantity(pool.getQuantity()-lossDiff);
            curPoolService.updateById(pool);

            //如果不是当天
            if(!IsToday.isToday(date)){
                QueryWrapper<HisPool> wrapper = new QueryWrapper<>();
                wrapper.eq("pool_no", poolNo);
                wrapper.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list = hisPoolService.list(wrapper);
                for (HisPool hisPool1 : list) {
                    hisPool1.setWeight(pool.getWeight()+feedDiff/Double.parseDouble(coefficient));
                    //减重
                    hisPool1.setWeight(pool.getWeight()-lossWeightDiff);
                    //损耗
                    hisPool1.setQuantity(hisPool1.getQuantity()-lossDiff);
                    hisPoolService.updateById(hisPool1);
                }
            }

        }
        R<String> r = R.success("成功");
        r.setStatusText("新增食耗记录成功!");
        return r;

    }

    @Override
    public List<EveryDayFeedLoss> selectEveryDayFeedLoss(List<String> poolNos, Date startTime, Date endTime) {

        if (poolNos == null || poolNos.size() == 0){
            poolNos = curPoolService.getPoolNos();
        }

        LinkedList<EveryDayFeedLoss> everyDayFeedLosses = new LinkedList<>();

        for (String poolId : poolNos) {

            EveryDayFeedLoss everyDayFeedLoss = new EveryDayFeedLoss();
            everyDayFeedLoss.setPoolNo(poolId);
            everyDayFeedLoss.setKey(poolId);
            //查询该塘
            CurPool curPool = curPoolService.getCurPoolByNo(poolId);
            everyDayFeedLoss.setArea(curPool.getArea());
            //每日食耗记录
            QueryWrapper<FeedLoss> wrapper = new QueryWrapper<>();
            wrapper.eq("pool_no", poolId);
            wrapper.between("date", startTime, endTime);
            List<FeedLoss> list = this.list(wrapper);
            //LinkedList<TodayFeedLoss> dataList = new LinkedList<>();
            HashMap<String, TodayFeedLoss> hashMap = new HashMap<>();
            double totalFeed = 0;
            int totalLoss = 0;
            double totalLossWeight = 0;
            for (FeedLoss feedLoss : list) {
                TodayFeedLoss todayFeedLoss = new TodayFeedLoss();
                todayFeedLoss.setDate(feedLoss.getDate());
                todayFeedLoss.setFeed(feedLoss.getFeed());
                todayFeedLoss.setLoss(feedLoss.getLoss());
                todayFeedLoss.setLossWeight(feedLoss.getLossWeight());
                todayFeedLoss.setPoolNo(feedLoss.getPoolNo());
                todayFeedLoss.setType(feedLoss.getType());
                //dataList.add(todayFeedLoss);

                if (hashMap.containsKey(feedLoss.getDate().toString())){
                    TodayFeedLoss todayFeedLoss1 = hashMap.get(feedLoss.getDate());
                    todayFeedLoss1.setFeed(todayFeedLoss1.getFeed()+feedLoss.getFeed());
                    todayFeedLoss1.setLoss(todayFeedLoss1.getLoss()+feedLoss.getLoss());
                    hashMap.put(feedLoss.getDate().toString(), todayFeedLoss1);
                }else {
                    hashMap.put(feedLoss.getDate().toString(), todayFeedLoss);
                }

                totalFeed += feedLoss.getFeed();
                totalLoss += feedLoss.getLoss();
                totalLossWeight += feedLoss.getLossWeight();
            }
            everyDayFeedLoss.setDataMap(hashMap);
            //everyDayFeedLoss.setDataList(dataList);
            everyDayFeedLoss.setTotalFeed(totalFeed);
            everyDayFeedLoss.setTotalLoss(totalLoss);
            everyDayFeedLoss.setTotalLossWeight(totalLossWeight);

            everyDayFeedLosses.add(everyDayFeedLoss);
        }



        return everyDayFeedLosses;
    }

    @Override
    public FeedGainWeight selectWeightIncrease(String poolNo, Date startTime, Date endTime, DailyLoss dailyLoss) {
        QueryWrapper<FeedLoss> wrapper = new QueryWrapper<>();
        wrapper.eq("pool_no", poolNo);
        wrapper.between("date", startTime, endTime);
        List<FeedLoss> list = this.list(wrapper);
        FeedGainWeight feedGainWeight = new FeedGainWeight();
        feedGainWeight.setFeed(0.0);
        feedGainWeight.setCoefficient(0.0);
        for (FeedLoss feedLoss : list) {
            feedGainWeight.setFeed(feedGainWeight.getFeed() + feedLoss.getFeed());
            if (feedLoss.getType()==1){
                feedGainWeight.setCoefficient(Double.parseDouble(baseDataService.selectValueByName("coefficient1")));
            }else if (feedLoss.getType()==2){
                feedGainWeight.setCoefficient(Double.parseDouble(baseDataService.selectValueByName("coefficient2")));
            }
            dailyLoss.setAmount(dailyLoss.getAmount() + feedLoss.getLoss());
            dailyLoss.setWeight(dailyLoss.getWeight() + feedLoss.getLossWeight());
        }
        if (feedGainWeight.getCoefficient() == 0){
            feedGainWeight.setGainWeight(0.0);
            return feedGainWeight;
        }
        feedGainWeight.setGainWeight(feedGainWeight.getFeed()/feedGainWeight.getCoefficient());
        return feedGainWeight;
    }

    @Override
    public List<RespSiteFeedLoss> selectSiteFeedLoss(List<String> siteNos, Date startTime, Date endTime) {
        //如果查询场号为空查询全部场
        if (siteNos == null || siteNos.size() == 0){
            siteNos = siteService.getAllSiteNo();
        }
        //包装对象
        LinkedList<RespSiteFeedLoss> list = new LinkedList<>();

        //遍历装填数据
        for (String siteNo : siteNos) {
            //获取该场基础信息
            Site site = siteService.getSiteByNo(siteNo);
            //初始化新
            RespSiteFeedLoss respSiteFeedLoss = new RespSiteFeedLoss();
            respSiteFeedLoss.setSiteNo(siteNo);
            respSiteFeedLoss.setArea(site.getArea());
            respSiteFeedLoss.setKey(siteNo+"-new");
            respSiteFeedLoss.setType(1);
            HashMap<String, SiteFeedLoss> dataMap = new HashMap<>();
            respSiteFeedLoss.setDataMap(dataMap);

            //初始化老
            RespSiteFeedLoss respSiteFeedLossOld = new RespSiteFeedLoss();
            respSiteFeedLossOld.setSiteNo(siteNo);
            respSiteFeedLossOld.setArea(site.getArea());
            respSiteFeedLossOld.setKey(siteNo+"-old");
            respSiteFeedLossOld.setType(2);
            HashMap<String, SiteFeedLoss> dataMapOld = new HashMap<>();
            respSiteFeedLossOld.setDataMap(dataMapOld);

            respSiteFeedLoss.setTotalFeed(0.0);
            respSiteFeedLoss.setTotalLoss(0);
            respSiteFeedLoss.setTotalLossWeight(0.0);
            respSiteFeedLossOld.setTotalFeed(0.0);
            respSiteFeedLossOld.setTotalLoss(0);
            respSiteFeedLossOld.setTotalLossWeight(0.0);


            Date tmpDate = new Date(startTime.getTime());

            //初始化dataMap
            while (tmpDate.getTime() <= endTime.getTime()){
                SiteFeedLoss siteFeedLoss = new SiteFeedLoss();
                SiteFeedLoss siteFeedLossOld = new SiteFeedLoss();
                siteFeedLoss.setDate(new Date(tmpDate.getTime()));
                siteFeedLossOld.setDate(new Date(tmpDate.getTime()));
                siteFeedLoss.setType(1);
                siteFeedLossOld.setType(2);
                siteFeedLoss.setFeed(0.0);
                siteFeedLoss.setLoss(0);
                siteFeedLoss.setLossWeight(0.0);
                siteFeedLossOld.setFeed(0.0);
                siteFeedLossOld.setLoss(0);
                siteFeedLossOld.setLossWeight(0.0);
                dataMap.put(tmpDate.toString(), siteFeedLoss);
                dataMapOld.put(tmpDate.toString(), siteFeedLossOld);
                tmpDate.setTime(tmpDate.getTime()+24*60*60*1000);
            }


            //查询该场的所有塘号
            List<String> poolNos = curPoolService.getPoolsBySiteNo(siteNo);
            if (poolNos == null || poolNos.size() == 0){
                continue;
            }
            //查询食耗记录
            QueryWrapper<FeedLoss> wrapper = new QueryWrapper<>();
            wrapper.in("pool_no", poolNos);
            wrapper.between("date", startTime, endTime);
            List<FeedLoss> feedLosses = this.list(wrapper);



            //累计在一起
            for (FeedLoss feedLoss : feedLosses) {

                //如果是新鳗

                if(feedLoss.getType() == 1){
                    SiteFeedLoss siteFeedLoss = dataMap.get(feedLoss.getDate().toString());
                    siteFeedLoss.setFeed(siteFeedLoss.getFeed() + feedLoss.getFeed());
                    siteFeedLoss.setLoss(siteFeedLoss.getLoss() + feedLoss.getLoss());
                    siteFeedLoss.setLossWeight(siteFeedLoss.getLossWeight() + feedLoss.getLossWeight());
                    respSiteFeedLoss.setTotalFeed(respSiteFeedLoss.getTotalFeed() + feedLoss.getFeed());
                    respSiteFeedLoss.setTotalLoss(respSiteFeedLoss.getTotalLoss() + feedLoss.getLoss());
                    respSiteFeedLoss.setTotalLossWeight(respSiteFeedLoss.getTotalLossWeight() + feedLoss.getLossWeight());

                }else if (feedLoss.getType() == 2){
                    SiteFeedLoss siteFeedLoss = dataMapOld.get(feedLoss.getDate().toString());
                    siteFeedLoss.setFeed(siteFeedLoss.getFeed() + feedLoss.getFeed());
                    siteFeedLoss.setLoss(siteFeedLoss.getLoss() + feedLoss.getLoss());
                    siteFeedLoss.setLossWeight(siteFeedLoss.getLossWeight() + feedLoss.getLossWeight());
                    respSiteFeedLossOld.setTotalFeed(respSiteFeedLossOld.getTotalFeed() + feedLoss.getFeed());
                    respSiteFeedLossOld.setTotalLoss(respSiteFeedLossOld.getTotalLoss() + feedLoss.getLoss());
                    respSiteFeedLossOld.setTotalLossWeight(respSiteFeedLossOld.getTotalLossWeight() + feedLoss.getLossWeight());
                }


            }

            list.add(respSiteFeedLoss);
            list.add(respSiteFeedLossOld);

        }


        return list;
    }

    @Override
    public List<FeedLossRecord> selectFeedLossRecord(List<String> poolNos, Date startTime, Date endTime, String userId) {
        if (poolNos == null || poolNos.size() == 0){
            poolNos = curPoolService.getPoolNos();
        }

        QueryWrapper<FeedLoss> wrapper = new QueryWrapper<>();
        wrapper.in("pool_no", poolNos);
        wrapper.between("date", startTime, endTime);
        if (userId != null && !userId.equals("")){
            wrapper.eq("user_id", userId);
        }
        List<FeedLoss> list = this.list(wrapper);

        LinkedList<FeedLossRecord> feedLossRecords = new LinkedList<>();
        HashMap<String, String> allUser = userService.getAllUser();

        for (FeedLoss feedLoss : list) {
            FeedLossRecord feedLossRecord = new FeedLossRecord();
            ReportBasic reportBasic = new ReportBasic();
            reportBasic.setPoolNo(feedLoss.getPoolNo());
            String s = allUser.get(feedLoss.getUserId());
            reportBasic.setReporter(s);
            reportBasic.setDate(feedLoss.getDate());
            reportBasic.setReportDate(feedLoss.getReportDate());
            feedLossRecord.setFeed(feedLoss.getFeed());
            feedLossRecord.setLoss(feedLoss.getLoss());
            feedLossRecord.setLossWeight(feedLoss.getLossWeight());
            feedLossRecord.setReportBasic(reportBasic);
            feedLossRecords.add(feedLossRecord);
        }

        return feedLossRecords;
    }
}
